//Realtime Optimally Adapting Meshes
import loader.Cfg;

import Landscape;
import Renderer;
import FPS;
import camera;
import Gpgpu;

import maths.Vec;

import derelict.sdl.sdl;

import std.stdio:writefln;

Camera cam;

bool flyMode = false;
bool wireframe = false;

static this() {
    cam = new Camera;
}

void keyDown(SDL_KeyboardEvent e){
	if(e.keysym.sym == SDLK_ESCAPE) 
		throw new Exception("KungFuDeathGrip");
	if(e.keysym.sym == SDLK_p){
		if(wireframe){
			renderer.modeTex();
			wireframe = false;
		}
		else{
			renderer.modeWire();
			wireframe = true;
		}
	}
    cam.keyDown(e.keysym.sym);
}

void keyUp(SDL_KeyboardEvent e){
    cam.keyUp(e.keysym.sym);
}

void mouseMotion(SDL_MouseMotionEvent e){
    if (e.x != 400 || e.y != 300) {
        cam.mouseMotion(e.x - 400, e.y - 300);
    }
}

void main(){
	auto cfgLoader = new CfgLoader;
	cfgLoader.load(`config\config.cfg`);
	auto cfg = cfgLoader.result();

	bool gpgpuEnabled = cfg.bool_(`gpgpu`);
	int mapSize = cfg.int_(`mapSize`);
	int pps1 = cfg.int_(`pPerSide`);

	if(gpgpuEnabled){
		gpgpu.start();
	}

	Landscape landscape;
	landscape = new Landscape(mapSize, pps1, gpgpuEnabled);

	if(gpgpuEnabled){
		gpgpu.computePi();
		gpgpu.clean();
	}

	cam.setMapSize(mapSize);
	renderer.initialize();

	scope(exit){
	}

	FPS fpsCounter = new FPS(1000);
	mainLoop:
	while(true){
		SDL_Event event;
        while (SDL_PollEvent(&event)) {
            switch (event.type) {
                case SDL_QUIT:
                    break mainLoop;
                case SDL_KEYDOWN:
                    keyDown(event.key);
                    break;
                case SDL_KEYUP:
                    keyUp(event.key);
                    break;
                case SDL_MOUSEMOTION:
                    mouseMotion(event.motion);
                    break;
				default:
					break;
			}
		}
		SDL_WarpMouse(400,300);

		fpsCounter.update();

		landscape.reset();
		landscape.tessellate();
	
		renderer.set();
	
		if(!flyMode){
			cam.position.y = landscape.height(cam.position.x,cam.position.z);
			landscape.viewPosition = vec3(cam.position.x, cam.position.y, cam.position.z);
			landscape.clipAngle = cam.horAngle;
		}
		cam.set();
		landscape.render();
		renderer.end();
		fpsCounter.nextFrame();
	}
}
